﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Noise.Modules;
using Noise.Utils;
using System.Diagnostics;

namespace NoiseLab
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }

        private void Main_Load(object sender, EventArgs e)
        {
            /*
            Module module = new RidgedMulti();
            
            PlanarNoiseMapBuilder mapBuilder = new PlanarNoiseMapBuilder(
                400, 400, // image size
                0.0, // border value
                module,
                -1.0, 1.0, // x bounds
                -1.0, 1.0, // z bounds
                false // not seamless 
                );

            GradientColour colours = new GradientColour();
            colours.AddGradientPoint(-1.0, Color.Black);
            colours.AddGradientPoint(0.5, Color.Green);
            colours.AddGradientPoint(2.0, Color.White);

            ImageBuilder imageBuilder = new ImageBuilder(
                mapBuilder.Build(), colours);

            noiseImage.Image = imageBuilder.Render();
            */
        }

        internal void SetModuleList(List<Module> modules)
        {
            TreeNode[] modulesNodes = treeView1.Nodes.Find("nodeModules", false);           

            Debug.Assert(modulesNodes.Length == 1);

            TreeNode modulesRoot = modulesNodes[0];
            modulesRoot.Nodes.Clear();

            SetModulesToNode(modulesRoot, modules);            
        }

        internal void ShowNoFreeModuleSlotsError()
        {
            MessageBox.Show("This module is full");
        }

        internal void ShowModuleTypeSelector(List<Type> _moduleTypes, Module module)
        {
            TypeSelectionDialog tsd = new TypeSelectionDialog(_moduleTypes);

            if (tsd.ShowDialog() == DialogResult.OK && CompleteAddModule != null)
            {
                CompleteAddModule(tsd.SelectedType, module);
            }
        }

        internal void SetCurrentNoiseImage(Image image)
        {
            noiseImage.Image = image;
        }

        internal void SetPropertyGridObject(Module module)
        {
            propertyGrid1.SelectedObject = module;
        }

        private void SetModulesToNode(TreeNode node, List<Module> modules)
        {
            foreach (Module module in modules)
            {
                TreeNode moduleNode = node.Nodes.Add(module.GetType().Name);
                moduleNode.Tag = module;
                moduleNode.ContextMenuStrip = ctxModulesContext;

                if (ModuleHasChildren(module))
                {
                    List<Module> children = new List<Module>();
                    children.AddRange(module.Modules);
                    SetModulesToNode(moduleNode, children);
                }
            }
        }

        private bool ModuleHasChildren(Module module)
        {
            for (int i = 0; i < module.ModuleCount; ++i)
            {
                if (module.Modules[i] != null) return true;
            }

            return false;
        }

        #region ~ Events ~
        private void addModuleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            object tag = ((TreeView)treeView1).SelectedNode.Tag;

            if (AddModuleClicked != null)
            {
                AddModuleClicked(tag,e);
            }
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            treeView1.SelectedNode = e.Node;
        }

        private void renderToolStripMenuItem_Click(object sender, EventArgs e)
        {
            object tag = ((TreeView)treeView1).SelectedNode.Tag;

            if (Render != null)
            {
                Render(tag, e);
            }
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {            
            Module tag = e.Node.Tag as Module;
            if (tag != null && ModuleSelected != null)
            {
                ModuleSelected(tag, e);
            }
        }

        public event EventHandler AddModuleClicked;

        public event AddModuleHandler CompleteAddModule;

        public event EventHandler Render;

        public event EventHandler ModuleSelected;
        

        #endregion        

        
    
        
    }
}
